<template>
  <div
    class="virtual-file-list-v2"
    ref="containerRef"
    @contextmenu="handleEmptyAreaContextMenu"
    @click="handleEmptyAreaClick"
  >
    <!-- 列表头部 -->
    <FileListHeader />

    <!-- TanStack Vue Virtual 高性能虚拟滚动 -->
    <div
      ref="scrollElementRef"
      class="virtual-scroll-container"
      :style="{
        height: `${containerHeight - 40 - 24}px`,
        overflow: 'auto',
      }"
      @contextmenu="handleEmptyAreaContextMenu"
    >
      <div
        :style="{
          height: `${virtualizer.getTotalSize()}px`,
          width: '100%',
          position: 'relative',
        }"
        @contextmenu="handleEmptyAreaContextMenu"
      >
        <div
          v-for="item in virtualizer.getVirtualItems()"
          :key="String(item.key)"
          :style="{
            position: 'absolute',
            top: 0,
            left: 0,
            width: '100%',
            height: `${item.size}px`,
            transform: `translateY(${item.start}px)`,
          }"
          class="virtual-file-item"
        >
          <FileListItem :item="props.items[item.index]" />
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from "vue";
import { useVirtualizer } from "@tanstack/vue-virtual";
import type { FileSystemItem } from "../types/fileSystem";
import { useFileStore } from "../stores/fileStore";
import FileListItem from "./FileListItem.vue";
import FileListHeader from "./FileListHeader.vue";

interface Props {
  items: FileSystemItem[];
  containerHeight?: number;
}

const props = withDefaults(defineProps<Props>(), {
  containerHeight: 600,
});

// DOM 引用
const containerRef = ref<HTMLElement>();
const scrollElementRef = ref<HTMLElement>();

// Store
const fileStore = useFileStore();

// TanStack Vue Virtual 虚拟化器配置
const virtualizer = useVirtualizer(
  computed(() => ({
    count: props.items.length,
    getScrollElement: () => scrollElementRef.value || null,
    estimateSize: () => 40, // 每个项目的估计高度
    overscan: 10, // 增加预渲染项目数量，提高滚动性能
  }))
);

// 空白区域右键菜单处理
const handleEmptyAreaContextMenu = (event: MouseEvent) => {
  event.preventDefault();

  // 检查是否点击在空白区域（而不是文件/文件夹项上）
  const target = event.target as HTMLElement;
  const isFileItem =
    target.closest(".file-list-item") || target.closest(".virtual-file-item");

  // 如果不是点击在文件项上，就是空白区域
  if (!isFileItem) {
    // 触发右键菜单（父组件会处理菜单显示）
    document.dispatchEvent(
      new CustomEvent("empty-area-contextmenu", {
        detail: { x: event.clientX, y: event.clientY },
      })
    );
  }
};

// 空白区域左键点击处理（取消选中）
const handleEmptyAreaClick = (event: MouseEvent) => {
  // 检查是否点击在空白区域（而不是文件/文件夹项上）
  const target = event.target as HTMLElement;
  const isFileItem =
    target.closest(".file-list-item") || target.closest(".virtual-file-item");

  // 如果不是点击在文件项上，就是空白区域，取消选中
  if (!isFileItem) {
    fileStore.clearSelection();
  }
};
</script>

<style scoped lang="scss">
.virtual-file-list-v2 {
  width: 100%;
  height: 100%;
  background: var(--el-bg-color);
  overflow: hidden;
  position: relative;
  // 启用硬件加速
  transform: translateZ(0);
  will-change: transform;
  // 优化重绘性能
  contain: layout style paint;

  .virtual-scroll-container {
    // 启用GPU加速滚动
    transform: translateZ(0);
    -webkit-overflow-scrolling: touch;

    // 自定义滚动条样式
    &::-webkit-scrollbar {
      width: 12px;
      height: 12px;
    }

    &::-webkit-scrollbar-track {
      background: var(--el-fill-color-light);
      border-radius: 6px;
    }

    &::-webkit-scrollbar-thumb {
      background: var(--el-border-color-darker);
      border-radius: 6px;
      border: 2px solid var(--el-fill-color-light);

      &:hover {
        background: var(--el-border-color-dark);
      }
    }

    &::-webkit-scrollbar-corner {
      background: var(--el-fill-color-light);
    }
  }

  // 虚拟滚动项目样式
  .virtual-file-item {
    // 优化渲染性能
    contain: layout style paint;
    // 减少重绘，但只在需要时使用 will-change
    &:hover {
      background-color: var(--el-fill-color-light);
      // 只在 hover 时启用 will-change
      will-change: background-color;
    }
  }

  // 确保深层样式一致性
  :deep(.virtual-file-item) {
    // 确保项目容器正确对齐
    display: flex;
    align-items: center;
    width: 100%;
    min-height: 40px;
    padding: 0 8px;

    // 优化文本渲染
    text-rendering: optimizeSpeed;
    -webkit-font-smoothing: antialiased;
  }

  // 确保滚动条样式一致
  :deep(*::-webkit-scrollbar) {
    width: 12px;
    height: 12px;
  }

  :deep(*::-webkit-scrollbar-track) {
    background: var(--el-fill-color-light);
    border-radius: 6px;
  }

  :deep(*::-webkit-scrollbar-thumb) {
    background: var(--el-border-color-darker);
    border-radius: 6px;
    border: 2px solid var(--el-fill-color-light);

    &:hover {
      background: var(--el-border-color-dark);
    }
  }

  :deep(*::-webkit-scrollbar-corner) {
    background: var(--el-fill-color-light);
  }
}

// 暗色主题支持
.dark .virtual-file-list-v2 {
  background: var(--el-bg-color-page);

  .virtual-scroll-container {
    &::-webkit-scrollbar-track {
      background: var(--el-fill-color-darker);
    }

    &::-webkit-scrollbar-thumb {
      background: var(--el-border-color-light);
      border-color: var(--el-fill-color-darker);

      &:hover {
        background: var(--el-border-color);
      }
    }
  }
}
</style>
